
// Copyright (C) 2007 Richard Uhler
// This file is part of Esiply.
//
// Esiply is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License, Version 2,
// as published by the Free Software Foundation.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

#ifndef _OBJECT_H_
#define _OBJECT_H_
#include <pthread.h>
//#include <gc_allocator.h>
#include <ext/hash_map>
#include <set>

#include "String.h"
#include "Value.h"
#include "ValueType.h"

// Property attributes
#define PA_EMPTY        0
#define PA_READ_ONLY    (1 << 0)
#define PA_DONT_ENUM    (1 << 1)
#define PA_DONT_DELETE  (1 << 2) 

class Object : public Value
{
public:
    typedef __gnu_cxx::hash_map<String*, std::pair<Value*, unsigned char>, hashstring, equalstring> PropertyMap;

    Object();
    Object(Value* value);
    Object(Value* value, Object* prototype, String* clss);
    virtual ValueType getType() const;
    virtual Boolean* toBoolean();
    virtual Object* toObject();
    virtual Value* toPrimitive();
    virtual Value* toPrimitive(ValueType type);
    virtual Number* toNumber();
    virtual String* toString();

    virtual bool isCallable() const;

    // Ecma 8.6.2.1 [[Get]]
    Value* get(String* name);

    // Ecma 8.6.2.2 [[Put]]
    // Name should be a String value.
    // virtual so Array can overwrite it
    virtual void put(String* name, Value* value, unsigned char attrib);

    // Ecma 8.6.2.3 [[CanPut]]
    // This returns a bool because I was having trouble with
    // returning a Boolean value (problems with global constructors
    // again). We know canPut is only called by the put method, which
    // doesn't make any use of the Boolean, so it can return a bool
    bool canPut(String* name, PropertyMap::iterator* piter = NULL);

    // Ecma 8.6.2.4 [[HasProperty]]
    Boolean* hasProperty(String* name);

    // Ecma 8.6.2.5 [[Delete]]
    Boolean* deleteProperty(String* name);

    // Ecma 8.6.2.6 [[DefaultValue]] (hint)
    Value* defaultValue();
    Value* defaultValue(ValueType hint);

    // Note: this is NOT Ecma 8.6.2.4 [[HasProperty]]. It only
    // looks in this object, and doesn't consult the prototype
    // object to find the property.
    bool has(String* name, PropertyMap::iterator* piter = NULL);

    unsigned char get_attributes(String* name);

    void get_enumerable(std::set<String*, ltstring>& enumerable);

    Object* get_prototype() const;
    void set_prototype(Object* proto);

    Value* get_value() const;
    void set_value(Value* value);

    String* get_class() const;
    void set_class(String* clss);
	
    // The Object prototype object.
    static Object* prototype;

    // The Global Object
    static Object* global;
	
	void lock();
	void unlock();
	~Object();
private:

    PropertyMap m_properties;
    Value* m_value;
    Object* m_prototype;
    String* m_class;
	//object Lock , in Multi Thread used
	pthread_mutex_t* m_lock;
};

#endif//_OBJECT_H_

